﻿using IAutoMapperGlobalConfiguration = AutoMapper.Internal.IGlobalConfiguration;
using IMapper = MicroCloud.Mapping.IMapper;

namespace MicroCloud.AutoMapper
{
    /// <summary>
    /// 自动映射模块(AutoMapper)
    /// </summary>
    [Description("自动映射模块(AutoMapper)")]
    public class AutoMapperPack : PackBase
    {
        /// <summary>
        /// 获取 模块级别
        /// </summary>
        public override PackLevel Level => PackLevel.Framework;

        #region 方法
        /// <summary>
        /// 将模块服务添加到依赖注入服务容器中
        /// </summary>
        /// <param name="services">依赖注入服务容器</param>
        /// <returns></returns>
        public override IServiceCollection AddServices(IServiceCollection services)
        {
            services.TryAddSingleton(new MapperConfigurationExpression());
            services.AddSingleton<IMapTuple, MapFromAndMapToProfile>();

            return services;
        }

        /// <summary>
        /// 应用模块服务
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public override void UsePack(IServiceProvider provider)
        {
            ILogger logger = provider.GetLogger<AutoMapperPack>();
            MapperConfigurationExpression cfg = provider.GetRequiredService<MapperConfigurationExpression>();

            //获取已注册到 IoC 的所有 Profile
            IMapTuple[] tuples = provider.GetServices<IMapTuple>().OrderBy(m => m.OrderNo).ToArray();
            foreach (IMapTuple mapTuple in tuples)
            {
                mapTuple.CreateMap();
                cfg.AllowNullCollections = true;
                cfg.AllowNullDestinationValues = true;
                cfg.AddProfile(mapTuple as Profile);
                logger.LogInformation("构建 {type} 对象映射配对", mapTuple.GetType());
            }

            IAutoMapperGlobalConfiguration configuration = new MapperConfiguration(cfg);
            IMapper mapper = new AutoMapperMapper(configuration);
            MapperExtensions.SetMapper(mapper);
            logger.LogInformation("完成对象映射器 {type} 到 MapperExtensions 的设置，共计 {count} 个映射配对。", mapper.GetType(), configuration.GetMappers().Count());

            IsEnabled = true;
        }

        #endregion
    }
}
